'''
 * CaRComp Execution Environment
 * 
 * Copyright (C) 2011 Taylor L. Riche
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
'''

from carcomp.framework import io_component
import socket, re

class NetWriterComponent(io_component.IOComponent):
    '''
    classdocs
    '''

    def __init__(self, name, node_name, dir_instance):
        '''
        Constructor
        '''
        io_component.IOComponent.__init__(self, name)
        self.__outputs__ = []
        self.__directory__ = dir_instance
        self._node_name = node_name
        
        
    def handle_input_stream(self, msg):
        # get the host_name and data out of the msg tuple
        try:
            host_name = msg[0]
            data = msg[1]
        except Exception:
            print('The msg argument to NetWriterComponent is not a (host_name, data) tuple')
            exit(2)
            
        m = re.search('BCAST;(\S+)', msg[0])
        if m is None:
            self.send(host_name, data)
        else:
            for de in self.__directory__.get_group(m.group(1)):
                if de.short_name != self._node_name:
                    #print(self._node_name + ':' + de.short_name)
                    self.send(de.short_name, data)

    def send(self, host_name, data):
        send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        address = self.__directory__.address(host_name)
        port = self.__directory__.listen_port(host_name)
        try:
            print('sending: {} to {}'.format(str(data),host_name))
            send_sock.connect((address, port))
            send_sock.sendall(data.encode('utf-8'))
        except socket.error as err:
            print('Error on connect to ' + str(address) + ':' + str(port))
            print(err)
        except socket.error as err:
            print('Error on send to ' + str(address) + ':' + (port))
            print(err)
            
        send_sock.close()     
    
    def cleanup(self):
        '''Cleanup any sockets that have been stored. Currently we don't store sockets'''
        for sock in self.__outputs__:
            sock.close()   